package com.xreal.common.log.desensitization;

import com.xreal.common.log.Log;
import com.xreal.common.utils.CertUtils;
import com.xreal.common.utils.PhoneUtils;
import org.slf4j.Logger;

import java.lang.reflect.Field;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @author yangzhongming
 * @desc 日志脱敏工具类
 * @date 2022/4/25
 */
@SuppressWarnings("unused")
public class LogDesensitization {


    private static final Logger logger = Log.get(LogDesensitization.class.getName());


    /**
     * 日志脱敏
     */
    public static String desensitization(Object o) {
        //String 类型的
        Class<?> aClass = o.getClass();
        //有该注解： DesensitizationEnableAnnotation的类才会被脱敏处理
        if (aClass.isAnnotationPresent(DesensitizationEnableAnnotation.class)) {
            StringBuilder stringBuilder = new StringBuilder();
            stringBuilder.append("{");
            Field[] fields = aClass.getDeclaredFields();
            for (int i = 0; i < fields.length; i++) {
                fields[i].setAccessible(true);
                stringBuilder.append(fields[i].getName());
                stringBuilder.append(":");
                try {
                    if (fields[i].isAnnotationPresent(DesensitizationAnnotation.class)) {
                        DesensitizationAnnotation desensitizationAnnotation = fields[i].getAnnotation(DesensitizationAnnotation.class);
                        DesensitizationType type = desensitizationAnnotation.type();
                        stringBuilder.append(convert(String.valueOf(fields[i].get(o)), type));
                    } else {
                        stringBuilder.append(fields[i].get(o));
                    }
                    if (i != fields.length - 1) {
                        stringBuilder.append(",");
                    } else {
                        stringBuilder.append("}");
                    }
                } catch (IllegalAccessException e) {
                    logger.error("数据脱敏异常：" + e.getMessage());
                }
            }
            return stringBuilder.toString();
        }
        return o.toString();
    }

    /**
     * 根据注解类型 转换数据
     *
     * @param value 需要转换的值
     * @param type  该脱敏数据类型
     * @return 脱敏后的数据
     */
    private static String convert(String value, DesensitizationType type) {
        String val = value;
        switch (type) {
            case PERSON_NAME:
                val = handlePersonName(value);
                break;
            case PERSON_PHONE_NO:
                val = handlePersonPhoneNo(value);
                break;
            case PERSON_CERT_NO:
                val = handlePersonCertNo(value);
                break;
            case PASSWORD:
                val = handlePassword(value);
                break;
            case BANCK_NAME:
                val = handleBankName(value);
                break;
            case BANCK_NO:
                val = handleBankNo(value);
                break;
        }
        return val;
    }


    /**
     * 转换银行卡号
     *
     * @param value 真实银行卡号
     * @return 脱敏银行卡号
     */
    private static String handleBankNo(String value) {
        String BANK_NO_REGEX = "(^\\d{19}$)";
        if (!value.matches(BANK_NO_REGEX)) {
            return value;
        }
        return value.replaceAll("(\\d{3})\\d{4}(\\d{4})", "$1****$2");
    }

    /**
     * 转换 银行名称
     *
     * @param value 真实银行名称
     * @return 脱敏后银行名称
     */
    private static String handleBankName(String value) {
        //正则表达式--匹配任意一个字符
        String reg = ".{1}";
        StringBuffer sb = new StringBuffer();
        Pattern p = Pattern.compile(reg);
        Matcher m = p.matcher(value);
        int i = 0;
        while (m.find()) {
            i++;
            if (i == 1)
                continue;
            if (i == value.length()) {
                continue;
            }
            m.appendReplacement(sb, "*");
        }
        m.appendTail(sb);
        return sb.toString();
    }

    /**
     * 转换密码
     *
     * @param value 真实密码
     * @return 脱敏密码
     */
    private static String handlePassword(String value) {
        //正则表达式--匹配任意一个字符
        String reg = ".{1}";
        StringBuffer sb = new StringBuffer();
        Pattern p = Pattern.compile(reg);
        Matcher m = p.matcher(value);
        while (m.find()) {
            m.appendReplacement(sb, "*");
        }
        m.appendTail(sb);
        return sb.toString();
    }

    /**
     * 转换 证件号
     *
     * @param value 真实证件号
     * @return 脱敏证件号
     */
    private static String handlePersonCertNo(String value) {
        return CertUtils.blurCert(value);
    }

    /**
     * 转换 姓名
     *
     * @param value 真实姓名
     * @return 脱敏姓名
     */
    private static String handlePersonName(String value) {
        //正则表达式--匹配任意一个字符
        String reg = ".{1}";
        StringBuffer sb = new StringBuffer();
        Pattern p = Pattern.compile(reg);
        Matcher m = p.matcher(value);
        int i = 0;
        while (m.find()) {
            i++;
            if (i == 1)
                continue;
            if (i == value.length()) {
                continue;
            }
            m.appendReplacement(sb, "*");
        }
        m.appendTail(sb);
        return sb.toString();

    }

    /**
     * 转换手机号
     *
     * @param value 真实手机号
     * @return 脱敏手机号
     */
    private static String handlePersonPhoneNo(String value) {
        return PhoneUtils.blurPhone(value);
    }

}

